package com.clp.protocol.iec104.apdu.asdu.info_obj.info_elem.file_transfer.dt_file;

import com.clp.protocol.core.common.frame.InitializableFrameClip;
import com.clp.protocol.core.common.frame.time2a.CP56Time2a;
import com.clp.protocol.core.utils.ByteUtil;
import com.clp.protocol.core.utils.DateUtil;
import com.clp.protocol.core.utils.StringUtil;
import com.clp.protocol.iec104.definition.ConstVal;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.Objects;

/**
 * 定义传输文件
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class DTFile implements InitializableFrameClip<DTFile> {
    /**
     * 文件名称长度（字节）
     */
    private int filenameBytesLen;
    /**
     * 文件名称
     */
    private String filename;
    /**
     * 文件属性
     */
    private DTFileProperty fileProperty;
    /**
     * 文件大小（字节）
     */
    private long fileSize;
    /**
     * 文件时间
     */
    private Date fileTime;

    @Override
    public DTFile initBy(ByteBuf buf) {
        // 文件名称长度
        this.filenameBytesLen = buf.readByte() & 0xFF;
        // 文件名称
        byte[] filenameBytes = new byte[filenameBytesLen]; buf.readBytes(filenameBytesLen);
        this.filename = StringUtil.decode(filenameBytes, "utf-8");
        // 文件属性
        this.fileProperty = new DTFileProperty().initBy(buf);
        // 文件大小
        byte[] fileSizeBytes = new byte[ConstVal.FILE_SIZE_LEN]; buf.readBytes(fileSizeBytes);
        this.fileSize = ByteUtil.bytes4ToLongLE(fileSizeBytes);
        // 文件时间
        byte[] fileTimeBytes = new byte[CP56Time2a.bytesLen]; buf.readBytes(fileTimeBytes);
        this.fileTime = DateUtil.CP56Time2aBytes7ToDate(fileTimeBytes);
        return this;
    }

    @Override
    public boolean isValid() {
        if (filenameBytesLen < 0 || filenameBytesLen > 0xFF) return false;
        if (filename == null || filename.equals("")) return false;
        if (fileProperty == null || !fileProperty.isValid()) return false;
        if (fileSize < 0 || fileSize > 0xFFFFFFFFL) return false;
        return fileTime != null;
    }

    @Override
    public void writeTo(ByteBuf buf) {
        // 文件 i 名称长度
        byte[] filenameBytes = StringUtil.encode(filename, "utf-8");
        buf.writeByte(filenameBytes.length);
        // 文件 i 名称
        buf.writeBytes(filenameBytes);
        // 文件 i 属性
        fileProperty.writeTo(buf);
        // 文件 i 大小
        buf.writeBytes(ByteUtil.longToBytes4LE(fileSize));
        // 文件 i 时间
        buf.writeBytes(DateUtil.dateToCP56Time2aBytes7(fileTime));
    }

    @Override
    public String toString() {
        // TODO 暂时这样
        return null;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DTFile dtFile = (DTFile) o;
        return filenameBytesLen == dtFile.filenameBytesLen && fileSize == dtFile.fileSize && Objects.equals(filename, dtFile.filename) && Objects.equals(fileProperty, dtFile.fileProperty) && Objects.equals(fileTime, dtFile.fileTime);
    }

    @Override
    public int hashCode() {
        return Objects.hash(filenameBytesLen, filename, fileProperty, fileSize, fileTime);
    }
}
